# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time    : 2025/3/27 23:41
@Author  : HZP
@File    : http.py
"""
from flask import Flask
from flask_cors import CORS
from flask_login import LoginManager
from flask_migrate import Migrate

from config import Config
from internal.exception.exception import CustomException
from internal.middleware import Middleware
from internal.router import Router
from pkg.response import Response, HttpCode
from pkg.response.response import json
from pkg.sqlalchemy import SQLAlchemy


class Http(Flask):
    def __init__(self, *args, db: SQLAlchemy,
                 login_manager: LoginManager,
                 migrate: Migrate,
                 middleware: Middleware,
                 conf: Config,
                 router: Router,
                 **kwargs):
        # 1.调用父类构造初始化
        super().__init__(*args, **kwargs)
        # 3.注册异常错误处理
        self.register_error_handler(Exception, self._register_error_handler)
        # 4.初始化配置
        self.config.from_object(conf)
        # 5.初始化数据库配置
        db.init_app(self)
        # with self.app_context():
        #     db.create_all()
        # 6.初始化数据库迁移内容
        migrate.init_app(self, db, directory="internal/migration")
        # 7.进行跨域配置
        CORS(self, resources={
            r"/*": {
                "origins": "*",
                "supports_credentials": True,
                # "methods": ["GET", "POST"],
                # "allow_headers": ["Content-Type"],
            }
        })
        # 8.初始化登录管理
        login_manager.init_app(self)
        # 9.初始化中间件
        login_manager.request_loader(middleware.request_loader)
        # 2.初始化路由
        router.register_router(self)

    def _register_error_handler(self, error: Exception):
        # 判断是否为CustomException 异常信息
        if isinstance(error, CustomException):
            return json(Response(code=error.code, message=error.message, data=error.data))
        if self.debug:
            raise error
        else:
            return json(Response(code=HttpCode.FAIL, message=str(error), data=None))
